using System;
using System.Collections.Generic;
using RawRestructure.Enums;

namespace RawRestructure.Models;

/// <summary>
/// 表示发送到工作站的数据包
/// </summary>
public class TcpPacket
{
    /// <summary>
    /// 数据包头部第一个字节 'T'
    /// </summary>
    public byte Header0 { get; set; } = 0x54;

    /// <summary>
    /// 数据包头部第二个字节 'i'
    /// </summary>
    public byte Header1 { get; set; } = 0x69;

    /// <summary>
    /// 命令类型
    /// </summary>
    public CommandType CommandType { get; set; }

    /// <summary>
    /// 数据长度
    /// </summary>
    public ushort DataLength { get; set; }

    /// <summary>
    /// 数据内容
    /// </summary>
    public byte[] Data { get; set; } = Array.Empty<byte>();

    /// <summary>
    /// 将数据包转换为字节数组
    /// </summary>
    /// <returns>字节数组</returns>
    public byte[] ToByteArray()
    {
        var result = new List<byte>();
        // 添加头部
        result.Add(Header0);
        result.Add(Header1);
         
        // 添加数据长度（小端序）
        result.Add((byte)(DataLength & 0xFF));
        
        // 添加命令类型
        result.Add((byte)CommandType);
        // 添加数据内容
        if (Data.Length > 0)
        {
            result.AddRange(Data);
        }
        
        return result.ToArray();
    }

    /// <summary>
    /// 从字节数组创建数据包
    /// </summary>
    /// <param name="data">字节数组</param>
    /// <returns>TcpPacket实例，如果数据格式不正确则返回null</returns>
    public static TcpPacket? FromByteArray(byte[] data)
    {
        if (data.Length < 5) // 最小包长度：2字节头部 + 1字节命令 + 2字节长度
            return null;

        // 验证头部
        if (data[0] != 0x54 || data[1] != 0x69)
            return null;

        var packet = new TcpPacket
        {
            Header0 = data[0],
            Header1 = data[1],
            CommandType = (CommandType)data[2],
            DataLength = (ushort)(data[3] | (data[4] << 8))
        };

        // 提取数据内容
        if (packet.DataLength > 0 && data.Length >= 5 + packet.DataLength)
        {
            packet.Data = new byte[packet.DataLength];
            Array.Copy(data, 5, packet.Data, 0, packet.DataLength);
        }

        return packet;
    }

    /// <summary>
    /// 创建数据包
    /// </summary>
    /// <param name="commandType">命令类型</param>
    /// <param name="data">数据内容</param>
    /// <returns>TcpPacket实例</returns>
    public static TcpPacket Create(CommandType commandType, byte[] data)
    {
        byte[] packetData;
        
        // 如果data.Length可以被2整除则Data=data,如果不行则需要在data后再增加一个00的字节
        if (data.Length % 2 == 0)
        {
            packetData = data;
        }
        else
        {
            packetData = new byte[data.Length + 1];
            Array.Copy(data, packetData, data.Length);
            packetData[data.Length] = 0x00; // 添加0x00字节
        }
        
        return new TcpPacket
        {
            CommandType = commandType,
            DataLength = (ushort)(packetData.Length + 1),
            Data = packetData
        };
    }

    /// <summary>
    /// 获取数据包描述信息
    /// </summary>
    /// <returns>描述字符串</returns>
    public override string ToString()
    {
        return $"TcpPacket [Command: {CommandType}, Length: {DataLength}]";
    }
} 